Decorator for user verificationΒΆ
The user should be an instance of User or AnonymousUser class.
Notes:
1. Consider a method that is expected to take a user as its first argument.
2. This decorator will only correctly wrap a function or static method,
and will fail if wrapping a bound method to a class.
This is because the decorator ignores the expectation to send self
as the first argument to a bound method.
import functools
class User(object):
"""A representation of a logged in user"""
def __init__(self, username, email):
self.username = username
self.email = email
class AnonymousUser(object):
"""An anonymous user; a stand-in for an actual user
that nonetheless is not an actual user
"""
def __init__(self):
self.username = None
self.email = None
def requires_user(func):
# Preserving the help of the inner function
@functools.wraps(func)
def inner(user, *args, **kwargs):
"""Verify that the user is truthy; if so, run the decorated method,
and if not, raise ValueError.
"""
# Ensure that user is truthy, and of the correct type.
# The "truthy" check will fail on anonymous users, since the
# AnonymousUser subclass has a `__nonzero__` method that
# returns False.
if user and isinstance(user, User):
return func(user, *args, **kwargs)
else:
raise ValueError('A valid user is required to run this method')
return inner
u1 = User('john', 'jmarlett@gmail.com')
u2 = AnonymousUser()
def func_01(user, x=3):
return x
@requires_user
def func_02(user, x=5):
return x
print(func_01(u1)) # 3
print(func_02(u1)) # 5
print(func_01(u2)) # 3
# print(func_02(u2))
# ValueError: A valid user is required to run this method